package com.corechina.apex_osswords.controller;

import com.corechina.apex_osswords.common.*;
import com.corechina.apex_osswords.domain.dto.SysLoginInfoDto;
import com.corechina.apex_osswords.domain.entity.SysLogs;
import com.corechina.apex_osswords.domain.entity.SysUser;
import com.corechina.apex_osswords.domain.vo.SysLoginInfoVo;
import com.corechina.apex_osswords.domain.vo.VerifyCodeVo;
import com.corechina.apex_osswords.service.IRedisService;
import com.corechina.apex_osswords.service.ISysLogsService;
import com.corechina.apex_osswords.service.ISysUser;
import com.corechina.apex_osswords.service.ISysUserTokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @program: apex_osswords
 * @description: 登录访问控制类
 * @author: cc
 * @create: 2022-03-07 14:51
 **/

@Api(tags = "登录")
@RestController
@RequestMapping("/sys/login")
public class SysLoginController {

    @Autowired
    private ISysUser iSysUser;

    @Autowired
    private ISysLogsService iSysLogsService;

    @Autowired
    private ISysUserTokenService iSysUserTokenService;

    @Autowired
    private IRedisService iRedisService;

    /**
     * 生成验证码
     */
    @GetMapping(value = "/getVerifyCode")
    @ApiOperation("获取验证码")
    public Response getVerifyCode() {
        try {
            RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
            VerifyCodeVo verifyCodeVo = new VerifyCodeVo();
            Map<String, String> codeMap = randomValidateCode.getRandcode();
            verifyCodeVo.setCodeBASE64(codeMap.get("code"));
            String uuid = UUID.randomUUID().toString().replace("-", "");
            verifyCodeVo.setUuid(uuid);
            iRedisService.remove(uuid);
            iRedisService.set(uuid,codeMap.get("randomString").toUpperCase());
            iRedisService.expire(uuid, 180);
            return Response.ok(verifyCodeVo);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.error();
        }
    }

    /**
     * 登录
     */
    @PostMapping(value = "/login")
    @ApiOperation("登录")
    public Response login(@RequestBody SysLoginInfoDto sysLoginInfoDto) {
        if(sysLoginInfoDto.getUuid().isEmpty() || sysLoginInfoDto.getVerifyCode().isEmpty()){
            return Response.error("未填写验证码");
        }
        if(!sysLoginInfoDto.getVerifyCode().toUpperCase().equals(iRedisService.get(sysLoginInfoDto.getUuid()))){
            return Response.error("验证码错误");
        }
        iRedisService.remove(sysLoginInfoDto.getUuid());
        //用户信息
        Integer loginType = sysLoginInfoDto.getLoginType();
        SysLogs sysLogs = new SysLogs();
        String pwd = "";
        String loginName = sysLoginInfoDto.getLoginName();
        sysLogs.setCreateTime(new Date());

        sysLogs.setIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
        sysLogs.setOperation("登录");

        SysUser sysUser = iSysUser.getByLoginName(sysLoginInfoDto.getLoginName());
        if(sysUser == null){
            throw new APEXOSSWordsException("账号或密码不正确");
        }
        pwd = new Md5Hash(sysLoginInfoDto.getPwd(), sysUser.getSalt()).toString();
        //账号不存在、密码错误
        if (!pwd.equals(sysUser.getPwd())) {
            sysLogs.setAfterData(loginName + "登录失败");
            iSysLogsService.add(sysLogs);
            throw new APEXOSSWordsException("账号或密码不正确");
        }
        sysLogs.setOperator(sysUser.getId());
        if (loginType == null) {
            loginType = Constant.LoginType.CLIENT_LOGIN.getCode();
        }

        //账号锁定
        if (sysUser.getEnabled() == 0) {
            sysLogs.setAfterData(loginName + "登录失败");
            iSysLogsService.add(sysLogs);
            throw new APEXOSSWordsException("账号已被锁定,请联系管理员");
        }
        sysUser.setPwd(pwd);
        SysLoginInfoVo sysLoginInfoVo = iSysUserTokenService.login(sysUser, loginType);

        if (sysLoginInfoVo != null) {
            sysLogs.setAfterData(loginName + "登录成功");
            iSysLogsService.add(sysLogs);
            return Response.ok(sysLoginInfoVo);
        }
        sysLogs.setAfterData(loginName + "登录失败");
        iSysLogsService.add(sysLogs);
        return Response.error(loginName + "登录失败");
    }

    /**
     * 退出
     */
    @GetMapping(value = "/logout")
    @ApiOperation("退出")
    public Response logout() {
        if (iSysUserTokenService.logout(ShiroUtils.getUserId())) {
            return Response.ok();
        }
        return Response.error("退出失败");
    }
}
